﻿//*************************************************************************
//面向服务的协作式智能交通系统仿真软件SoC-ITSS v2.1 alpha
//发布单位：西北工业大学--巴黎高科MINES机器人与群智能系统联合实验室
//团队负责人：张凯龙 Zhang Kailong
//团队成员：张大方、杨安胜、王敏、谢策、王雨佳、谢尘玉等
//联系我们：kl.zhang@nwpu.edu.cn
//2012-2021
//*************************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

//*******************************************************
//
//文件名(File Name):           SuperVehicleManager.cs
//
//数据表(Tables):              nothing 
//          修改理由：         创建类
//
//*******************************************************

namespace CyberCarSimulation.Regulation
{
    //车辆管理类的封装类，一辆车对应一个SuperVehicleManager
    //一个SuperVehicleManager对象中会包含多个VehicleManager对象
    class SuperVehicleManager
    {
        public VehicleManager[] VehicleManagers = new VehicleManager[5];    //用于存储不同临界区的预约消息
        public readonly string ID;      //车辆ID
        public int Priority;            //车辆的当前优先级
        public int LaneID;      //车辆所处车道
        public readonly string SectionID;   //车辆的临界区序列
        public readonly string Original_SectionID;  //车辆的原临界区序列
        public int CS_Count = 0;    //临界区的数量，未增加0标志的车道
        public float[] Ts;          //到达各临界区的时间
        public float[] Te;          //离开各临界区的时间
        public readonly float Total_Dis;        //车辆当前已走过的距离（已更新）
        public readonly int Original_Priority;  //车辆原优先级
        public int HaveTokenCount = 0;  //当前已申请的临界区的数量
        public bool[] Token;            //车辆对现在临界区的占有情况，用于按顺序申请临界区，若为true则表示申请成功
        public bool[] Left;             //标志各车辆是否已经离开对应的临界区,
        //若为false则表示未离开临界区，若已通过该临界区，则标识为true
        public int IsAuthorized = 0;    //用于判断当前适量是否已经经过了executeAlgorithmPrior算法的CSAuthorize()的判断,
        //若其值为0，则表示V被未经过判断
        //若其值为1，则表示V已经过判断，被授权了所有临界区
        //若其值为2，则表示V已经过判断，被授权了部分临界区
        //若其值为3，则表示V已经过判断，未被授权临界区
        public bool IsJudged = false;   //标致当前车辆是否经过了授权判断。若其值为true,则标志其已进行过判断
        public bool[] RealTsToken;      //经过了executeAlgorithmPrior算法判断是否会产生延迟后，其真实到达情况。
        //若车辆在某临界区未被延迟，则标志为true，表示此时可以使用ts的值
        //若被延迟，则其值为false， 而使用的时候采用的值是999999
        public bool[] RealTeToken;      //经过了executeAlgorithmPrior算法判断是否会产生延迟后，其真实离开情况。
        //若车辆在某临界区未被延迟，则标志为true，表示此时可以使用ts的值
        //若被延迟，则其值为false， 而使用的时候采用的值是999999

        public SuperVehicleManager(string ID, int LaneID, float[] Ts, float[] Te, float Total_Dis, string SectionIDs, int Priority)
        {
            this.ID = ID;        //SuperVehicleMangerde的ID和Vehicle的ID是一模一样的
            this.LaneID = LaneID;
            this.SectionID = SectionIDs;
            this.Original_SectionID = SectionIDs;
            this.Priority = Priority;
            this.Original_Priority = Priority;
            this.SectionID = this.SectionID.Replace("_", "");
            this.CS_Count = this.SectionID.Length;
           
            this.Ts = Ts;
            this.Te = Te;
            this.Total_Dis = Total_Dis;
            this.Token = new bool[5];
            this.Token[0] = true;
            this.Token[1] = false;
            this.Token[2] = false;
            this.Token[3] = false;
            this.Token[4] = false;
            this.Left = new bool[5];
            this.IsAuthorized = 0;
            this.RealTsToken = new bool[5];
            this.RealTeToken = new bool[5];
            for (int i = 0; i < 5; i++)
            {
                this.Left[i] = false;
                this.RealTsToken[i] = false;
                this.RealTeToken[i] = false;
            }

            //用于实现死锁判断
            while (this.SectionID.Length < 7)
            {
                this.SectionID += "0";
            }
            //车辆信息的队列
            for (int i = 0; i < 5; i++)
            {
                this.VehicleManagers[i] = null;
            }

            //按照车辆的临界区数量设置消息
            switch (this.CS_Count)
            {
                case 1:
                    this.VehicleManagers[int.Parse(this.SectionID[0].ToString())]     //几个VehicleManger的ID和SuperVehicleManger的ID一模一样
                        = new VehicleManager(ID, LaneID, Ts[1], Te[1], Total_Dis, this.SectionID[0].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[0].ToString())].setCSCount(this.CS_Count);
                    break;
                case 2:
                    this.VehicleManagers[int.Parse(this.SectionID[0].ToString())]
                        = new VehicleManager(ID, LaneID, Ts[1], Te[1], Total_Dis, this.SectionID[0].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[0].ToString())].setCSCount(this.CS_Count);
                    this.VehicleManagers[int.Parse(this.SectionID[1].ToString())]
                        = new VehicleManager(ID, LaneID, Ts[2], Te[2], Total_Dis, this.SectionID[1].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[1].ToString())].setCSCount(this.CS_Count);
                    break;
                case 3:
                    this.VehicleManagers[int.Parse(this.SectionID[0].ToString())]
                        = new VehicleManager(ID, LaneID, Ts[1], Te[1], Total_Dis, this.SectionID[0].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[0].ToString())].setCSCount(this.CS_Count);
                    this.VehicleManagers[int.Parse(this.SectionID[1].ToString())]
                        = new VehicleManager(ID, LaneID, Ts[2], Te[2], Total_Dis, this.SectionID[1].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[1].ToString())].setCSCount(this.CS_Count);
                    this.VehicleManagers[int.Parse(this.SectionID[2].ToString())]
                        = new VehicleManager(ID, LaneID, Ts[3], Te[3], Total_Dis, this.SectionID[2].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[2].ToString())].setCSCount(this.CS_Count);
                    break;
                case 4:
                    this.VehicleManagers[int.Parse(this.SectionID[0].ToString())]
                        = new VehicleManager(ID, LaneID, Ts[1], Te[1], Total_Dis, this.SectionID[0].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[0].ToString())].setCSCount(this.CS_Count);
                    this.VehicleManagers[int.Parse(this.SectionID[1].ToString())]
                        = new VehicleManager(ID, LaneID, Ts[2], Te[2], Total_Dis, this.SectionID[1].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[1].ToString())].setCSCount(this.CS_Count);
                    this.VehicleManagers[int.Parse(this.SectionID[2].ToString())]
                        = new VehicleManager(ID, LaneID, Ts[3], Te[3], Total_Dis, this.SectionID[2].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[2].ToString())].setCSCount(this.CS_Count);
                    this.VehicleManagers[int.Parse(this.SectionID[3].ToString())]
                        = new VehicleManager(ID, LaneID, Ts[4], Te[4], Total_Dis, this.SectionID[3].ToString(), Priority, true);
                    this.VehicleManagers[int.Parse(this.SectionID[3].ToString())].setCSCount(this.CS_Count);
                    break;

                default:
                    MessageBox.Show("Error occurs in SuperVehicleManager Func in MultiSCSFIFO_Sche.cs", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
            }
        }

        //获取车辆的位置信息
        public float getTotal_Dis()
        {
            return this.Total_Dis;
        }
        public string getID()
        {
            return this.ID;
        }
        public void setTs(float[] ts)
        {
            this.Ts = ts;
        }
        public void setTe(float[] te)
        {
            this.Te = te;
        }

    }
}
